﻿using Delphi.Apoll.Eod;
using Delphi.Apoll.Util;
using System;
using System.ServiceProcess;
using System.Threading;
using System.Timers;

namespace Delphi.Iduna {
    // Based on http://stackoverflow.com/questions/12885013/windows-service-with-timer

    // Install service: http://www.c-sharpcorner.com/UploadFile/naresh.avari/develop-and-install-a-windows-service-in-C-Sharp/

    /**************************************************************************
    *  IMPORTANT NOTE: Windows Service is running as 'NT AUTHORITY\SYSTEM'
    *  - Add Login in SQL Server
    *  - Grant Access Rights
    **************************************************************************/

    partial class EodService : ServiceBase {
        private System.Timers.Timer _timer;
        private Thread _workingThread;
        private Exception _asyncException;

        public EodService() {
            InitializeComponent();
            ServiceName = "Delphi EodService (Iduna)";
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
        }

        void UnhandledExceptionHandler (object sender, UnhandledExceptionEventArgs e) {
            _asyncException = e.ExceptionObject as Exception;
            Stop();
        }

        protected override void OnStart(string[] args) {
            /*
            _timer = new System.Timers.Timer(60*30*1000); // 30 Minutes
            _timer.AutoReset = true;
            _timer.Elapsed += new ElapsedEventHandler(TimerElapsed);
            _timer.Start();
            Log.Write("Service Started");
            */
            _workingThread = new Thread(new ThreadStart(WorkingHorse));
            Log.Write("Service Started");
        }

        private void TimerElapsed(object sender, ElapsedEventArgs args) {
            // Call to working function
            try {
                using (EodUpdater up = new EodUpdater()) {
                    up.UpdateAll();
                }
            } catch (Exception e) {
                Log.Write(e);
            }
        }

        protected override void OnStop() {
            // TODO: Add code here to perform any tear-down necessary to stop your service.
            /*
            _timer.Stop();
            _timer = null;
            Log.Write("Service Stopped");
            */
            if(_asyncException != null) {
                Log.Write("Service Stopped with error");
                throw new InvalidOperationException("Unhandled exception in service");
            }
            Log.Write("Service Stopped");
        }

        private void WorkingHorse() {
            Thread.Sleep((int)TimeSpan.FromMinutes(1).TotalMilliseconds);
            try {
                using (EodUpdater up = new EodUpdater()) {
                    up.UpdateAll();
                }
            } catch (Exception e) {
                Log.Write(e);
                throw new InvalidOperationException("An error occured");
            }
        }
    }
}
